#version 330 core
struct Material{
  sampler2D diffuse;
  sampler2D specular;
  float shininess;
};

struct Light{
   // 聚光的位置向量（来计算光的方向向量）、聚光的方向向量和一个切光角
  vec3 position;//固定点光源
  vec3 direction;//光源方向

  vec3 ambient;
  vec3 diffuse;
  vec3 specular;

  float cutOff; // 内圆锥切光角
  float outerCutOff; // 外圆锥切光角


//		//光照衰减用三变量
//		float constant;
//		float linear;
//		float quadratic;
};

out vec4 FragColor;
in vec2 TexCoords;

uniform Material material;
uniform Light light;

uniform vec3 viewPos;

in vec3 Normal;
in vec3 FragPos;

void main()
{
    //ambient
    vec3 ambient = light.ambient * vec3(texture2D(material.diffuse, TexCoords));

    //diffuse
    vec3 norm = normalize(Normal);
    vec3 lightDir = normalize(light.position - FragPos);//固定点光源
    //vec3 lightDir = normalize(-light.direction);//定向平行光源
    float diff = max(dot(norm, lightDir), 0.0f);
    vec3 diffuse = light.diffuse * (diff * vec3(texture2D(material.diffuse, TexCoords)));

    //specular
    vec3 viewDir = normalize(viewPos - FragPos);
    vec3 reflectDir = reflect(-lightDir, norm);
    float spec = pow(max(dot(viewDir, reflectDir), 0.0f), material.shininess);
    vec3 specular = light.specular * (spec * vec3(texture2D(material.specular, TexCoords)));

    //all
    vec3 result =  ambient + diffuse + specular;

    //手电筒
    float theta = dot(lightDir, normalize(-light.direction));
    float epsilon = light.cutOff - light.outerCutOff;
    float intensity = clamp((theta - light.outerCutOff)/epsilon, 0.0f, 1.0f); //我们使用了clamp函数，它把第一个参数约束(Clamp)在了0.0到1.0之间。这保证强度值不会在[0, 1]区间之外
    FragColor = vec4(result * intensity, 1.0f);
}
